package model

import (
	"fastdp-ops/pkg/server/api/models"
	"fmt"
	"net"
	"strings"
	"time"
)

// PreCheck 部署前检查：主机名去重、防火墙状态、Agent端口连通性
func PreCheck(onlineHosts map[string]models.Machines, agentPort string) error {

	// 检查1：主机名是否重复
	if err := checkHostnameDuplicate(onlineHosts); err != nil {
		return err
	}
	// 检查2：Agent端口连通性
	if err := checkAgentPort(onlineHosts, agentPort); err != nil {
		return err
	}

	return nil
}

// checkHostnameDuplicate 确保所有在线主机的hostname唯一
func checkHostnameDuplicate(onlineHosts map[string]models.Machines) error {
	hostnameCount := make(map[string]int)
	duplicateHosts := make(map[string][]string) // key: hostname, value: 重复的IP列表

	// 统计主机名出现次数
	for ip, machine := range onlineHosts {
		hostname := machine.Hostname
		hostnameCount[hostname]++
		duplicateHosts[hostname] = append(duplicateHosts[hostname], ip)
	}

	// 检查是否有重复
	var duplicates []string
	for hostname, ips := range duplicateHosts {
		if len(ips) > 1 {
			duplicates = append(duplicates, fmt.Sprintf("主机名 %q 重复（IP: %v）", hostname, ips))
		}
	}

	if len(duplicates) > 0 {
		return fmt.Errorf("主机名重复：%s", strings.Join(duplicates, "; "))
	}
	return nil
}

// checkAgentPort 检查所有在线主机的Agent端口是否可达
func checkAgentPort(onlineHosts map[string]models.Machines, agentPort string) error {
	var portErrors []string
	timeout := 2 * time.Second // 短超时，快速探测

	for ip := range onlineHosts {
		addr := fmt.Sprintf("%s:%s", ip, agentPort)
		// 尝试TCP连接探测端口
		conn, err := net.DialTimeout("tcp", addr, timeout)
		if err != nil {
			portErrors = append(portErrors, fmt.Sprintf("主机 %s 端口 %s 不通：%v", ip, agentPort, err))
			continue
		}
		conn.Close() // 连接成功后关闭
		fmt.Printf("   ✅ 主机 %s 端口 %s 连通正常\n", ip, agentPort)
	}

	if len(portErrors) > 0 {
		return fmt.Errorf("Agent端口连通性检查失败：%s", strings.Join(portErrors, "; "))
	}
	return nil
}
